package com.lzy.concertticket.aop.log;

import cn.hutool.json.JSONUtil;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

import java.lang.reflect.Method;
import java.util.Arrays;

@Slf4j
@Aspect
@Component
@Order(10)
public class ApiLogAspect {
    @Pointcut("@annotation(com.lzy.concertticket.aop.log.ApiLog)")
    void apiLogPointcut() {}

    @Pointcut("execution(* com.lzy.concertticket.controller.*.*(..))")
    void controllerPointcut() {}

    @Around("apiLogPointcut()")
    public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
        //  日志打印
        //  获取目标对象
        Object target = joinPoint.getTarget();
        //  获取目标方法Method对象
        Method method = ((MethodSignature) joinPoint.getSignature()).getMethod();
        //  获取ApiLog注解
        ApiLog apiLog = method.getAnnotation(ApiLog.class);
        String title = apiLog.title();

        //  获取类名
        String className = target.getClass().getName();
        //  获取方法名
        String methodName = joinPoint.getSignature().getName();
        //  获取参数
        Object[] args = joinPoint.getArgs();
        //  记录开始时间
        long startTime = System.currentTimeMillis();

        log.info("==========>【{}】{}#{}({})", title,className, methodName, args);

        //  执行目标函数
        Object result = joinPoint.proceed(args);

        //  记录结束时间
        long endTime = System.currentTimeMillis();

        log.info("<==========【{}】{}#{} complete,expensive {}ms, result: {}", title,className, methodName, endTime - startTime, JSONUtil.toJsonStr(result));

        return result;
    }
}
